home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / Win95 Secrets / SETUP.Z / LIBDUMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-19  |  6.2 KB  |  207 lines

  1. //==================================
  2. // PEDUMP - Matt Pietrek 1995
  3. // FILE: LIBDUMP.C
  4. //==================================
  5.  
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <ctype.h>
  10. #include "common.h"
  11. #include "objdump.h"
  12. #include "libdump.h"
  13. #include "extrnvar.h"
  14.  
  15. PSTR PszLongnames = 0;
  16.  
  17. DWORD ConvertBigEndian(DWORD bigEndian);
  18.  
  19. void DisplayArchiveMemberHeader(
  20.     PIMAGE_ARCHIVE_MEMBER_HEADER pArchHeader,
  21.     DWORD fileOffset )
  22. {
  23.     printf("Archive Member Header (%08X):\n", fileOffset);
  24.  
  25.     printf("  Name:     %.16s", pArchHeader->Name);
  26.     if ( pArchHeader->Name[0] == '/' && isdigit(pArchHeader->Name[1]) )
  27.         printf( "  (%s)\n", PszLongnames + atoi(pArchHeader->Name+1) );
  28.     printf("\n");
  29.  
  30.     printf("  Date:     %.12s\n", pArchHeader->Date);
  31.     printf("  UserID:   %.6s\n", pArchHeader->UserID);
  32.     printf("  GroupID:  %.6s\n", pArchHeader->GroupID);
  33.     printf("  Mode:     %.8s\n", pArchHeader->Mode);
  34.     printf("  Size:     %.10s\n", pArchHeader->Size);
  35. }
  36.  
  37. void DumpFirstLinkerMember(PVOID p)
  38. {
  39.     DWORD cSymbols = *(PDWORD)p;
  40.     PDWORD pMemberOffsets = MakePtr( PDWORD, p, 4 );
  41.     PSTR pSymbolName;
  42.     unsigned i;
  43.  
  44.     cSymbols = ConvertBigEndian(cSymbols);
  45.     pSymbolName = MakePtr( PSTR, pMemberOffsets, 4 * cSymbols );
  46.     
  47.     printf("First Linker Member:\n");
  48.     printf( "  Symbols:         %08X\n", cSymbols );
  49.     printf( "  MbrOffs   Name\n  --------  ----\n" );
  50.         
  51.     for ( i = 0; i < cSymbols; i++ )
  52.     {
  53.         DWORD offset;
  54.         
  55.         offset = ConvertBigEndian( *pMemberOffsets );
  56.         
  57.         printf("  %08X  %s\n", offset, pSymbolName);
  58.         
  59.         pMemberOffsets++;
  60.         pSymbolName += strlen(pSymbolName) + 1;
  61.     }
  62. }
  63.  
  64. void DumpSecondLinkerMember(PVOID p)
  65. {
  66.     DWORD cArchiveMembers = *(PDWORD)p;
  67.     PDWORD pMemberOffsets = MakePtr( PDWORD, p, 4 );
  68.     DWORD cSymbols;
  69.     PSTR pSymbolName;
  70.     PWORD pIndices;
  71.     unsigned i;
  72.  
  73.     cArchiveMembers = cArchiveMembers;
  74.  
  75.     // The number of symbols is in the DWORD right past the end of the
  76.     // member offset array.
  77.     cSymbols = pMemberOffsets[cArchiveMembers];
  78.  
  79.     pIndices = MakePtr( PWORD, p, 4 + cArchiveMembers * sizeof(DWORD) + 4 );
  80.  
  81.     pSymbolName = MakePtr( PSTR, pIndices, cSymbols * sizeof(WORD) );
  82.     
  83.     printf("Second Linker Member:\n");
  84.     
  85.     printf( "  Archive Members: %08X\n", cArchiveMembers );
  86.     printf( "  Symbols:         %08X\n", cSymbols );
  87.     printf( "  MbrOffs   Name\n  --------  ----\n" );
  88.  
  89.     for ( i = 0; i < cSymbols; i++ )
  90.     {
  91.         printf("  %08X  %s\n", pMemberOffsets[pIndices[i] - 1], pSymbolName);
  92.         pSymbolName += strlen(pSymbolName) + 1;
  93.     }
  94. }
  95.  
  96. void DumpLongnamesMember(PVOID p, DWORD len)
  97. {
  98.     PSTR pszName = (PSTR)p;
  99.     DWORD offset = 0;
  100.  
  101.     PszLongnames = (PSTR)p;     // Save off pointer for use when dumping
  102.                                 // out OBJ member names
  103.  
  104.     printf("Longnames:\n");
  105.     
  106.     // The longnames member is a series of null-terminated string.  Print
  107.     // out the offset of each string (in decimal), followed by the string.
  108.     while ( offset < len )
  109.     {
  110.         unsigned cbString = lstrlen( pszName )+1;
  111.  
  112.         printf("  %05u: %s\n", offset, pszName);
  113.         offset += cbString;
  114.         pszName += cbString;
  115.     }
  116. }
  117.  
  118. void DumpLibFile( LPVOID lpFileBase )
  119. {
  120.     PIMAGE_ARCHIVE_MEMBER_HEADER pArchHeader;
  121.     BOOL fSawFirstLinkerMember = FALSE;
  122.     BOOL fSawSecondLinkerMember = FALSE;
  123.     BOOL fBreak = FALSE;
  124.  
  125.     if ( strncmp(lpFileBase, IMAGE_ARCHIVE_START,
  126.                             IMAGE_ARCHIVE_START_SIZE ) )
  127.     {
  128.         printf("Not a valid .LIB file - signature not found\n");
  129.         return;
  130.     }
  131.     
  132.     pArchHeader = MakePtr(PIMAGE_ARCHIVE_MEMBER_HEADER, lpFileBase,
  133.                             IMAGE_ARCHIVE_START_SIZE);
  134.  
  135.     while ( pArchHeader )
  136.     {
  137.         DWORD thisMemberSize;
  138.         
  139.         DisplayArchiveMemberHeader( pArchHeader,
  140.                                     (PBYTE)pArchHeader - (PBYTE) lpFileBase );
  141.         printf("\n");
  142.  
  143.         if ( !strncmp(pArchHeader->Name, IMAGE_ARCHIVE_LINKER_MEMBER, 16) )
  144.         {
  145.             if ( !fSawFirstLinkerMember )
  146.             {
  147.                 DumpFirstLinkerMember( (PVOID)(pArchHeader + 1) );
  148.                 printf("\n");
  149.                 fSawFirstLinkerMember = TRUE;
  150.             }
  151.             else if ( !fSawSecondLinkerMember )
  152.             {
  153.                 DumpSecondLinkerMember( (PVOID)(pArchHeader + 1) );
  154.                 printf("\n");
  155.                 fSawSecondLinkerMember = TRUE;
  156.             }
  157.         }
  158.         else if(!strncmp(pArchHeader->Name,IMAGE_ARCHIVE_LONGNAMES_MEMBER,16))
  159.         {
  160.             DumpLongnamesMember( (PVOID)(pArchHeader + 1),
  161.                                  atoi(pArchHeader->Size) );
  162.             printf("\n");
  163.         }
  164.         else    // It's an OBJ file
  165.         {
  166.             DumpObjFile( (PIMAGE_FILE_HEADER)(pArchHeader + 1) );
  167.         }
  168.  
  169.         // Calculate how big this member is (it's originally stored as 
  170.         // as ASCII string.
  171.         thisMemberSize = atoi(pArchHeader->Size)
  172.                         + IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR;
  173.  
  174.         thisMemberSize = (thisMemberSize+1) & ~1;   // Round up
  175.  
  176.         // Get a pointer to the next archive member
  177.         pArchHeader = MakePtr(PIMAGE_ARCHIVE_MEMBER_HEADER, pArchHeader,
  178.                                 thisMemberSize);
  179.  
  180.         // Bail out if we don't see the EndHeader signature in the next record
  181.         __try
  182.         {
  183.             if ( strncmp(pArchHeader->EndHeader, IMAGE_ARCHIVE_END, 2) )
  184.                 break;
  185.         }
  186.         __except( TRUE )    // Should only get here if pArchHeader is bogus
  187.         {
  188.             fBreak = TRUE;  // Ideally, we could just put a "break;" here,
  189.         }                   // but BC++ doesn't like it.
  190.         
  191.         if ( fBreak )   // work around BC++ problem.
  192.             break;
  193.     }
  194. }
  195.  
  196. // Routine to convert from big endian to little endian
  197. DWORD ConvertBigEndian(DWORD bigEndian)
  198. {
  199.     __asm {
  200.         mov     eax,[bigEndian]
  201.         xchg    ah,al
  202.         ror     eax,16
  203.         xchg    ah,al
  204.     }
  205. }
  206.  
  207.